/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package unilearn.bo;

import java.util.ArrayList;
import java.util.List;
import unilearn.dao.PersonDAO;
import unilearn.dao.PersonRoleDAO;
import unilearn.dao.RoleDAO;
import unilearn.dao.SubjectDAO;
import unilearn.dao.SubjectMarkerDAO;
import unilearn.dao.SubjectStudentDAO;
import unilearn.vo.Person;
import unilearn.vo.PersonRole;
import unilearn.vo.Role;
import unilearn.vo.Subject;
import unilearn.vo.SubjectMarker;
import unilearn.vo.SubjectStudent;

/**
 *
 * @author Yat
 */
public class SubjectManagement {

    private AccessValidator validator;
    private PersonDAO personDAO;
    private SubjectDAO subjectDAO;
    private SubjectMarkerDAO subjectMarkerDAO;
    private SubjectStudentDAO subjectStudentDAO;

    public SubjectManagement() {
        validator = null;
        personDAO = null;
        subjectDAO = null;
        subjectMarkerDAO = null;
        subjectStudentDAO = null;
    }

    public SubjectManagement(AccessValidator validator, PersonDAO personDAO, SubjectDAO subjectDAO, SubjectMarkerDAO subjectMarkerDAO, SubjectStudentDAO subjectStudentDAO) {
        this();
        this.validator = validator;
        this.personDAO = personDAO;
        this.subjectDAO = subjectDAO;
        this.subjectMarkerDAO = subjectMarkerDAO;
        this.subjectStudentDAO = subjectStudentDAO;
    }

    public void setPersonDAO(PersonDAO personDAO) {
        this.personDAO = personDAO;
    }

    public void setSubjectDAO(SubjectDAO subjectDAO) {
        this.subjectDAO = subjectDAO;
    }

    public void setSubjectMarkerDAO(SubjectMarkerDAO subjectMarkerDAO) {
        this.subjectMarkerDAO = subjectMarkerDAO;
    }

    public void setSubjectStudentDAO(SubjectStudentDAO subjectStudentDAO) {
        this.subjectStudentDAO = subjectStudentDAO;
    }

    public void setValidator(AccessValidator validator) {
        this.validator = validator;
    }

    public List<Subject> getAllSubjects() throws Exception {
        return subjectDAO.getAll();
    }

    public List<Subject> getSubjects(Person person) throws Exception {
        return getSubjects(person, validator.getRole(person));
    }

    public List<Subject> getSubjects(Person person, Role role) throws Exception {
//        System.out.println("This person is " + role.getName() + ".");//***
        if (role.getName().equals("staff")) {
            return this.getAllSubjects();
        } else if (role.getName().equals("lecturer")) {
            List<Subject> ss = getConvernorSubjects(person);
            if (ss == null) {
                ss = getMarkerSubjects(person);
            } else {
                ss.addAll(getMarkerSubjects(person));
            }
            return ss;
        } else if (role.getName().equals("student")) {
            return getStudentSubjects(person);
        }

        return null;
    }

    public List<Subject> getStudentSubjects(Person person) throws Exception {
        List<SubjectStudent> sss = subjectStudentDAO.getAll();
        if ((sss == null) || (sss.isEmpty())) {
            return null;
        }

        List<Subject> subs = new ArrayList();
        for (SubjectStudent ss : sss) {
            if (ss.getPersonId() == person.getId()) {
                Subject s = subjectDAO.get(ss.getSubjectCode());
                subs.add(subjectDAO.get(ss.getSubjectCode()));
            }
        }

        return subs;
    }

    public List<Person> getSubjectStudents(Subject subject) throws Exception {
        SubjectStudent searchSs = new SubjectStudent();
        searchSs.setSubjectCode(subject.getSubjectCode());
//        System.out.println("[getSubjectStudents][0]" + searchSs.toString());//***
        List<SubjectStudent> sss = subjectStudentDAO.find(searchSs);
        if ((sss == null) || (sss.isEmpty())) {
            return null;
        }

        List<Person> students = new ArrayList();
        for (SubjectStudent ss : sss) {
//            System.out.println("[getSubjectStudents][1](" + ss.getPersonId() + ") " + ss.toString());//***
            Person p = personDAO.get(ss.getPersonId());
            if (p != null) {
//                System.out.println("[getSubjectStudents][2]" + p.toString());//***
                students.add(p);
            } else {
//                System.out.println("p is null.");
            }
        }

        return students;
    }

    public List<Person> getSubjectMarkers(Subject subject) throws Exception {
        SubjectMarker searchSm = new SubjectMarker();
        searchSm.setSubjectCode(subject.getSubjectCode());
        List<SubjectMarker> sms = subjectMarkerDAO.find(searchSm);
        if ((sms == null) || (sms.isEmpty())) {
            return null;
        }
        List<Person> markers = new ArrayList();
        for (SubjectMarker sm : sms) {
            Person p = personDAO.get(sm.getPersonId());
            if (p != null) {
                markers.add(p);
            }
        }

        return markers;
    }

    public List<Subject> getMarkerSubjects(Person person) throws Exception {
        List<SubjectMarker> sms = subjectMarkerDAO.getAll();
        if ((sms == null) || (sms.isEmpty())) {
            return null;
        }

        List<Subject> subs = new ArrayList();
        for (SubjectMarker sm : sms) {
            if (sm.getPersonId() == person.getId()) {
                subs.add(subjectDAO.get(sm.getSubjectCode()));
            }
        }

        return subs;
    }

    public List<Subject> getConvernorSubjects(Person person) throws Exception {
        List<Subject> ss = this.getAllSubjects();
        if ((ss == null) || (ss.isEmpty())) {
            return null;
        }

        List<Subject> subs = new ArrayList();
        for (Subject s : ss) {
            if (s.getConvernorId() == person.getId()) {
                subs.add(s);
            }
        }

        return subs;
    }

    public Subject getSubject(String subjectCode) throws Exception {
        return subjectDAO.get(subjectCode);
    }

    public Subject createSubject(Subject subject) throws Exception {
        return subjectDAO.insert(subject);
    }

    public Subject updateSubject(Subject subject) throws Exception {
        return subjectDAO.update(subject);
    }

    public void removeSubject(Subject subject) throws Exception {
        subjectDAO.delete(subject);
    }

    public void setConvernor(Subject subject, Person person) throws Exception {
        subject.setConvernorId(person.getId());
        this.updateSubject(subject);
    }

    public void removeConvernor(Subject subject) throws Exception {
        subject.setConvernorId(0);
        this.updateSubject(subject);
    }

    public List<SubjectMarker> getMarkers(Subject subject) throws Exception {
        SubjectMarker marker = new SubjectMarker();
        marker.setSubjectCode(subject.getSubjectCode());
        return subjectMarkerDAO.find(marker);
    }

    public void setMarker(Subject subject, Person person) throws Exception {
        SubjectMarker marker = new SubjectMarker();
        marker.setSubjectCode(subject.getSubjectCode());
        marker.setPersonId(person.getId());
        List<SubjectMarker> sms = subjectMarkerDAO.find(marker);
        if ((sms != null) && (!sms.isEmpty())) {
            return;
        }

        subjectMarkerDAO.insert(marker);
    }

    public void removeMarker(Subject subject, Person person) throws Exception {
        SubjectMarker marker = new SubjectMarker();
        marker.setSubjectCode(subject.getSubjectCode());
        marker.setPersonId(person.getId());
        List<SubjectMarker> sms = subjectMarkerDAO.find(marker);
        if ((sms != null) && (!sms.isEmpty())) {
            marker = sms.get(0);
            subjectMarkerDAO.delete(marker);
        }
    }

    public List<SubjectStudent> getStudents(Subject subject) throws Exception {
        SubjectStudent student = new SubjectStudent();
        student.setSubjectCode(subject.getSubjectCode());
        return subjectStudentDAO.find(student);
    }

    public void setStudent(Subject subject, Person person) throws Exception {
        SubjectStudent student = new SubjectStudent();
        student.setSubjectCode(subject.getSubjectCode());
        student.setPersonId(person.getId());
        List<SubjectStudent> sss = subjectStudentDAO.find(student);
        if ((sss != null) && (!sss.isEmpty())) {
            return;
        }

        subjectStudentDAO.insert(student);
    }

    public void removeStudent(Subject subject, Person person) throws Exception {
        SubjectStudent student = new SubjectStudent();
        student.setSubjectCode(subject.getSubjectCode());
        student.setPersonId(person.getId());
        List<SubjectStudent> sss = subjectStudentDAO.find(student);
        if ((sss != null) && (!sss.isEmpty())) {
            student = sss.get(0);
            subjectStudentDAO.delete(student);
        }
    }
}
